package com.init.bootframe.system.service.impl;

import com.init.bootframe.system.dao.IUserDao;
import com.init.bootframe.system.service.IUserService;
import com.init.bootframe.system.vo.*;
import com.init.bootframe.util.TmompConstant;
import com.init.bootframe.util.TmompUser;
import com.init.bootframe.util.TmompUtils;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 用户service
 */
@Service
public class UserServiceImpl implements IUserService {

    /**
     * 获取reques对象
     */
    @Autowired
    private HttpServletRequest request;


    @Autowired
    private IUserDao userDao;//用户dao

    /**
     * 日志
     */
    private static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);



    /**
     * 分页 list查询
     */
    @Override
    public JSONObject findUserList(UserVO userVO) {
        JSONObject jsonObject = new JSONObject();
        // 运营人员需要查看下级
        if (TmompConstant.BaseDataConstant.DEFAULT_VALUE_TWO.equals(userVO.getDataType())) {
            UserVO user = TmompUser.getCurrentUserInfo();
            userVO.setOrgCode(user.getOrgCode());
            userVO.setBusinessId(user.getBusinessId());
        }
        // 查询集合数据总数
        int total = userDao.findListCount(userVO);
        List<UserVO> resultLsit = new ArrayList<UserVO>();
        if (total > 0) {
            resultLsit = userDao.findList(userVO);
        }
        jsonObject.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_ROWS, resultLsit);
        jsonObject.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_TOTAL, total);
        return jsonObject;
    }

    /**
     * list 查询
     */
    @Override
    public List<UserVO> findList() {
        UserVO userVO = new UserVO();
        return userDao.findList(userVO);
    }

    /**
     * 详情查询
     */
    @Override
    public UserVO findUser(UserVO userVO) {
        UserVO user = userDao.findUser(userVO);
        if (null != userVO) {
            // 查询用户角色信息
            UserRoleVO userRoleVO = new UserRoleVO();
            userRoleVO.setUserId(userVO.getUserId());
            List<UserRoleVO> userRoleList = userDao.findUserRoleList(userRoleVO);
            user.setUserRoles(userRoleList);
        }
        return user;
    }

    /**
     * 添加
     */
    @Override
    public Map<String, Object> addUser(UserVO userVO) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        try {
            String password = userVO.getCardNo().substring(12, 18);
            // 设置初始密码
            userVO.setPassword(TmompUtils.strToMD5(password));
            userVO.setStatus(TmompConstant.BaseDataConstant.STATUS_EFFECTIVE);
            // 添加用户
            userDao.insert(userVO);
            // 向中间表添加用户关系数据
            //系统人员
            if(TmompConstant.BaseDataConstant.DATA_TYPE_SYSTEM.equals(userVO.getDataType())){
                userDao.insertUserOrg(userVO);
            }
            // 增加用户角色
            List<String> userRoles = userVO.getRoleIds();
            if (null != userRoles && userRoles.size() > 0) {
                for (int i = 0; i < userRoles.size(); i++) {
                    UserRoleVO userRoleVO = new UserRoleVO();
                    userRoleVO.setUserId(userVO.getUserId());
                    userRoleVO.setRoleId(userRoles.get(i));
                    userDao.addUserRole(userRoleVO);
                }
            }
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.TRUE);
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_MSG, "添加用户成功！");
            resultMap.put("userId", userVO.getUserId());
            logger.debug("添加用户成功！");
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.FALSE);
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_MSG, "添加用户失败！");
            logger.debug("添加用户异常！");
            throw new RuntimeException("添加用户异常！");
        }
        return resultMap;
    }
    /**
     * 判断账号是否唯一
     */
    @Override
    public Map<String, Object> judgeAccount(UserVO userVO) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        if (null != userVO.getAccount() && userVO.getAccount() != "") {
            // 判断账号是否唯一
            if (judge(userVO.getAccount())) {
                resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.FALSE);
                resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_MSG, "账号已存在!");
                logger.debug("用户账号已存在！");
            } else {
                resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.TRUE);
            }
        } else {
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.TRUE);
        }
        return resultMap;
    }

    /**
     * 判断账号是否唯一
     *
     * @param account
     */
    private boolean judge(String account) {
        boolean t = false;
        // 根据账号查询用户
        UserVO user = new UserVO();
        user.setAccount(account);
        user.setStatus(TmompConstant.BaseDataConstant.STATUS_EFFECTIVE);
        UserVO userJude = userDao.findUser(user);
        if (null != userJude && userJude.getAccount().equals(account)) {
            t = true;
        }
        return t;
    }

    /**
     * 更新
     */
    @Override
    public Map<String, Object> updateUser(UserVO userVO) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        try {
            //系统人员
            if(TmompConstant.BaseDataConstant.DATA_TYPE_SYSTEM.equals(userVO.getDataType())){
                // 先删除组织
                userDao.deleteUserOrg(userVO);
                userDao.insertUserOrg(userVO);
            }
            // 更新用户信息
            userDao.update(userVO);
            // 删除用户角色
            UserRoleVO delUserRoleVO = new UserRoleVO();
            delUserRoleVO.setUserId(userVO.getUserId());
            userDao.deleteUserRole(delUserRoleVO);
            // 增加用户角色
            List<String> userRoles = userVO.getRoleIds();
            if (null != userRoles && userRoles.size() > 0) {
                for (int i = 0; i < userRoles.size(); i++) {
                    UserRoleVO userRoleVO = new UserRoleVO();
                    userRoleVO.setUserId(userVO.getUserId());
                    userRoleVO.setRoleId(userRoles.get(i));
                    userDao.addUserRole(userRoleVO);
                }
            }
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.TRUE);
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_MSG, "更新用户成功！");
            logger.debug("更新用户成功！");
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.FALSE);
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_MSG, "更新用户失败！");
            logger.debug("更新用户异常！");
            throw new RuntimeException("更新用户异常！");
        }
        return resultMap;
    }

    /**
     * 删除
     */
    @Override
    public Map<String, Object> deleteUser(UserVO userVO) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            userVO.setStatus(TmompConstant.BaseDataConstant.STATUS_INVALID);
            userDao.delete(userVO);
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.TRUE);
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_MSG, "删除用户成功！");
            logger.debug("删除用户成功！");
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.FALSE);
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_MSG, "删除用户失败！");
            logger.debug("删除用户异常！");
            throw new RuntimeException("删除用户异常！");
        }
        return resultMap;
    }

    /**
     * 修改密码
     */
    @Override
    public Map<String, Object> updatePassword(UserVO userVO) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        try {
            userVO.setPassword(TmompUtils.strToMD5(userVO.getPassword()));
            userDao.update(userVO);
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.TRUE);
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_MSG, "修改成功！");
            logger.debug("密码修改成功！");
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.FALSE);
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_MSG, "修改密码异常！");
            logger.debug("修改密码异常！");
            throw new RuntimeException("修改密码异常！");
        }
        return resultMap;
    }

    /**
     * 查询当前登陆用户信息
     * @return
     */
    @Override
    public UserVO findLoginUser() {
        // 声明用户对象
        UserVO userInfoVO = null;
        Object obj = request.getSession().getAttribute("user");
        if (null != obj) {
            userInfoVO = (UserVO) obj;
        }
        return userInfoVO;
    }

    /**
     * 注销当前用户 清理session 在线状态
     */
    @Override
    public Map<String, Object> quit() {
        // 返回消息对象
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.TRUE);
        resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_MSG, "成功登出系统！");
        resultMap.put("userId", TmompUser.getCurrentUserId());
        logger.info("退出登录.");
        // 设置seesion失效
        request.getSession().setAttribute("user", null);
        // Redis储存缓存用户失效
        // redisUtils.set(TmompConstant.RedisConstant.REDIS_KEY_PREFIX_SYSTEM_USER.concat(userVO.getAccessToken()),
        // "", 1);
        return resultMap;
    }








    /**
     * 登录
     */
    @Override
    public Map<String, Object> login(UserVO userVO) throws Exception {
        // 返回消息对象
        Map<String, Object> resultMap = new HashMap<String, Object>();
        try {
            userVO.setStatus(TmompConstant.BaseDataConstant.STATUS_EFFECTIVE);
            // 将base64格式转为MD5存储
            userVO.setPassword(TmompUtils.strToMD5(TmompUtils.undoBase64(userVO.getPassword())));
            // 查询用户详细信息
            UserVO userInfo = userDao.findUser(userVO);
            if (null != userInfo) {
                // 只有运营数据类型才能后台登录,普通用户只能登录前台
                // if ("0".equals(userVO.getLoginType()) &&
                // "1".equals(userInfo.getDataType())) {
                // resultMap.put(BaseDataConstant.DEFAULT_VALUE_RESULT,
                // Boolean.FALSE);
                // resultMap.put(BaseDataConstant.DEFAULT_VALUE_MSG,
                // "登录失败，当前用户未开通权限！");
                // return JSONObject.fromObject(resultMap).toString();
                // }
                // 查询用户角色信息
                UserRoleVO userRoleVO = new UserRoleVO();
                userRoleVO.setUserId(userInfo.getUserId());
                List<UserRoleVO> userRoleList = userDao.findUserRoleList(userRoleVO);
                // 判断用户是否已经授权
                if (null != userRoleList && userRoleList.size() > 0) {
                    // 设置用户登录类型,0表示后台，1表示前台
                    userInfo.setLoginType(userVO.getLoginType());
                    // 查询用户所有栏目权限
                    List<MenuVO> menuList = userDao.findUserPermissionsList(userInfo);
                    // 查询用户所有操作权限
                    List<ModuleVO> modelList = userDao.findUserModelList(userInfo);
                    // 栏目权限与操作权限封装
                    List<MenuVO> userMenus = installMenuData(menuList, modelList);
                    userInfo.setUserMenus(userMenus);

                    // Redis临时储存手机端登录用户
                    // redisUtils.set(TmompConstant.RedisConstant.REDIS_KEY_PREFIX_SYSTEM_USER.concat(accessToken),
                    // userInfo, RedisConstant.TOKEN_LOGIN_DEFUALT_TIME);

                    // 获取系统配置信息并存储认证信息
                    Properties settings = TmompUtils.loadProperties("settings.properties");
                    logger.debug("appid:" + settings.getProperty(TmompConstant.SettingsConstant.PARAMER_NAME_APPID));
                    logger.debug("secret:" + settings.getProperty(TmompConstant.SettingsConstant.PARAMER_NAME_SECRET));
                    // 应用appId
                    userInfo.setAppId(settings.getProperty(TmompConstant.SettingsConstant.PARAMER_NAME_APPID));
                    // 应用secret
                    userInfo.setSecret(settings.getProperty(TmompConstant.SettingsConstant.PARAMER_NAME_SECRET));

                    // 用户对象保存在session回话中
                    request.getSession().setAttribute("user", userInfo);

                    resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.TRUE);
                    resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_MSG, "成功登录系统！");
                    resultMap.put("userVO", userInfo);
                } else {
                    resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.FALSE);
                    resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_MSG, "登录失败，当前用户未开通权限！");
                }
            } else {
                resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.FALSE);
                resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_MSG, "登录失败，请输入正确的帐号与密码！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_RESULT, Boolean.FALSE);
            resultMap.put(TmompConstant.BaseDataConstant.DEFAULT_VALUE_MSG, "用户登录失败！");
        }
        return resultMap;
    }

    /**
     * 重新组装菜单操作权限数据
     *
     * @param userMenus
     *            用户菜单栏目权限
     * @param moduleList
     *            用户操作功能权限
     * @return
     */
    private List<MenuVO> installMenuData(List<MenuVO> userMenus, List<ModuleVO> moduleList) {
        List<MenuVO> menuList = new ArrayList<>();
        if (null != userMenus && userMenus.size() > 0) {
            for (int i = 0; i < userMenus.size(); i++) {
                MenuVO menuVO = userMenus.get(i);
                // 组装操作权限
                if (null != moduleList) {
                    if (moduleList.size() > 0) {
                        List<ModuleVO> modules = new ArrayList<ModuleVO>();
                        for (int k = 0; k < moduleList.size(); k++) {
                            ModuleVO moduleVO = moduleList.get(k);
                            if (menuVO.getMenuId().equals(moduleVO.getMenuId())) {
                                modules.add(moduleVO);
                            }
                        }
                        menuVO.setModuleList(modules);
                    }
                }
                if ("0".equals(menuVO.getParentMenuId())) {
                    installRecursionData(menuVO, userMenus, moduleList);
                    menuList.add(menuVO);
                }
            }
        }
        return menuList;
    }

    /**
     * 递归，判断当前节点下面是否含有子节点
     *
     * @param userMenus
     *            用户菜单栏目权限
     *
     * @param moduleList
     *            用户操作功能权限
     * @param menuVO
     *            当前被执行菜单
     */
    private void installRecursionData(MenuVO menuVO, List<MenuVO> userMenus, List<ModuleVO> moduleList) {
        List<MenuVO> childMenuList = new ArrayList<MenuVO>();
        for (int i = 0; i < userMenus.size(); i++) {
            MenuVO childMenuVO = userMenus.get(i);
            // 组装操作权限
            if (null != moduleList && moduleList.size() > 0) {
                List<ModuleVO> modules = new ArrayList<ModuleVO>();
                for (int k = 0; k < moduleList.size(); k++) {
                    ModuleVO moduleVO = moduleList.get(k);
                    if (menuVO.getMenuId().equals(moduleVO.getMenuId())) {
                        modules.add(moduleVO);
                    }
                }
                menuVO.setModuleList(modules);
            }
            if (menuVO.getMenuId().equals(childMenuVO.getParentMenuId())) {
                installRecursionData(childMenuVO, userMenus, moduleList);
                childMenuList.add(childMenuVO);
            }
        }
        menuVO.setChildMenus(childMenuList);
    }
}
